/**
 * @file  EInput
 * @author xiao_xie
 * @date 2025-03-24
 */

import { CloseCircleOutlined } from "@ant-design/icons";
import classNames from "classnames";
import React, { ForwardRefRenderFunction, Ref, forwardRef, useImperativeHandle, useState } from "react";

type Props = {
    defaultValue?: string; // 默认值
    placeholder?: string;
    value?: string;
    onChange?: (e: string) => void;
    className?: string;
    style?: React.CSSProperties;
    icon?: React.ReactNode;
    iconPosition?: "start" | "end";
    type?: "text" | "password";
    allowClear?: boolean; // 是否显示清除按钮
    required?: boolean; // 是否必填
    disabled?: boolean; // 是否禁用
    readOnly?: boolean; // 是否只读
    pattern?: RegExp; // 正则表达式
    validator?: (value: string) => boolean | string; // 自定义校验函数,返回boolean或错误信息
    errorMessage?: string; // 错误提示信息
    onValidate?: (valid: boolean, errors: string[]) => void; // 校验结果回调函数
};

export type EInputRef = {
    /** 获取底层 input 元素 */
    nativeElement: HTMLInputElement | null;
    /** 手动触发校验 */
    validate: () => boolean;
    /** 清空输入内容 */
    clear: () => void;
    /** 获取当前值 */
    getValue: () => string;
};

const EInput: ForwardRefRenderFunction<EInputRef, Props> = ({
    type = "text",
    defaultValue,
    value: propsValue,
    placeholder = "请输入...",
    onChange,
    className,
    style,
    icon,
    iconPosition,
    allowClear = false,
    required = false,
    pattern,
    validator,
    errorMessage = "输入不合法",
    onValidate,
    readOnly = false,
    disabled = false,
}, ref) => {
    const cls = classNames(
        "outline-none border border-solid border-gray px-2 py-1 pr-12 rounded-md w-full hover:border-black transition-all",
        className,
        { 'opacity-50 cursor-not-allowed pointer-events-none': disabled }
    );


    const inputRef = React.useRef<HTMLInputElement>(null); // 非受控组件使用
    const [showClear, setShowClear] = useState(false);
    const [inputValue, setInputValue] = useState(defaultValue || '');
    // 受控模式：当父组件传入 value 时，使用受控模式
    const isControlled = propsValue !== undefined;
    const [errors, setErrors] = useState<string[]>([]);
    const [isTouched, setIsTouched] = useState(false); // 是否已触摸（用于首次未输入时不显示错误）

    // 暴露给父组件的方法
    useImperativeHandle(ref, () => ({
        nativeElement: inputRef.current,
        validate: () => {
            const value = isControlled ? propsValue || "" : inputValue;
            if (!value.trim()) {
                setIsTouched(true);
                setErrors(["必填项"]);
                onValidate?.(false, ["必填项"]);
                return false;
            }
            const errors = validateInput(value);
            setErrors(errors);
            onValidate?.(errors.length === 0, errors);
            return errors.length === 0;
        },
        clear: () => {
            if (!isControlled) setInputValue("");
            onChange?.("");
            setShowClear(false);
        },
        getValue: () => isControlled ? propsValue || "" : inputValue,
        
    }));

    // 统一校验逻辑
    const validateInput = (value: string) => {
        const newErrors: string[] = [];
        if (required && !value.trim()) {
            newErrors.push("必填项");
        }
        if (pattern && !pattern.test(value)) {
            newErrors.push(errorMessage);
        }
        // 3. 自定义校验函数（优先级最高）
        if (validator) {
            const customResult = validator(value);
            if (typeof customResult === "string") {
                newErrors.push(customResult);
            } else if (!customResult) {
                newErrors.push(errorMessage);
            }
        }
        return newErrors;
    }

    // 触发校验
    const triggerValidate = (value: string) => {
        const newErrors = validateInput(value);
        setErrors(newErrors);
        onValidate?.(newErrors.length === 0, newErrors);
    };

    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        if (isControlled) {
            // 受控模式下，父组件通过 onChange 更新 value
            onChange?.(e.target.value);
        } else {
            // 非受控模式下，内部管理 state
            setInputValue(e.target.value);
            onChange?.(e.target.value);
        }
        setShowClear(allowClear && e.target.value !== "");
        triggerValidate(e.target.value); // 触发校验
    };

    const handleBlur = () => {
        setIsTouched(true); // 标记为已触摸
        if (!isTouched) {
            triggerValidate(inputValue); // 触发校验
        }
    };
    // 错误样式类名
    const errorCls = classNames(
        "border-red-500 hover:border-red-600", // 错误时红色边框
        className
    );
    const handleClear = () => {
        if (!isControlled) {
            setInputValue('');
        }
        onChange?.("");
        setShowClear(false)
    }


    return (
        <div className="relative ">
            {icon && (
                <span className={`absolute top-1 ${iconPosition === "start" ? "left-2" : "right-2"}`}>
                    {icon}
                </span>
            )}
            <input
                ref={inputRef}
                readOnly={readOnly}
                disabled={disabled}
                type={type}
                value={isControlled ? propsValue : inputValue}
                placeholder={placeholder}
                style={{ ...style }}
                onChange={handleChange}
                className={classNames(cls, { [errorCls]: errors.length > 0 && isTouched })}
                onBlur={handleBlur}
            />
            {/* 错误信息展示 */}
            {isTouched && errors.length > 0 && (
                <div className="text-red-500 text-xs mt-1 pl-2">
                    {errors.join(", ")}
                </div>
            )}
            {allowClear && showClear && (
                <CloseCircleOutlined
                    className="absolute right-8 top-2 cursor-pointer"
                    onClick={handleClear}
                />
            )}
        </div>
    );
};




export default forwardRef(EInput);
